package com.iphanta.community.following.service.impl;

import com.baidu.fsg.uid.UidGenerator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iphanta.community.common.UserUtils;
import com.iphanta.community.common.entity.Page;
import com.iphanta.community.common.utils.RedisKeyUtils;
import com.iphanta.community.following.entity.Dynamic;
import com.iphanta.community.following.traffic.vo.UserSimpleInfo;
import com.iphanta.community.mq.message.Notification;
import com.iphanta.community.user.entity.Relation;
import com.iphanta.community.following.entity.UserBehavior;
import com.iphanta.community.user.mapper.RelationMapper;
import com.iphanta.community.following.mapper.UserBehaviorMapper;
import com.iphanta.community.following.service.FollowingService;
import com.iphanta.community.following.traffic.FollowRequest;
import com.iphanta.community.following.traffic.FollowResponse;
import com.iphanta.community.following.traffic.FollowingsFollowersRequest;
import com.iphanta.community.following.traffic.FollowingsFollowersResponse;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author 墨声 E-mail: zehong.hongframe.huang@gmail.com
 * create time: 2/23/22 2:15 PM
 */
@Service
public class FollowingServiceImpl implements FollowingService {

    private final static Logger LOGGER = LoggerFactory.getLogger(FollowingService.class);

    @Autowired
    private RelationMapper relationMapper;

    @Autowired
    private UserBehaviorMapper userBehaviorMapper;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FollowResponse follow(FollowRequest request) {
        FollowResponse response = new FollowResponse();
        Relation relation = this.relationMapper.selectOne(request.getFollowing(), UserUtils.getUid());
        Boolean following = Boolean.FALSE;
        if (Objects.isNull(relation)) {
            relation = new Relation();
            relation.setId(this.uidGenerator.getUID());
            relation.setFollowerId(UserUtils.getUid());
            relation.setFollowingId(request.getFollowing());
            relation.setIsDel(0);
            relation.setUpdateTime(new Date());
            relation.setCreateTime(new Date());

            this.relationMapper.insert(relation);
            String newlyFans = RedisKeyUtils.INSTANCE.key("newly_fans", request.getFollowing());
            this.redisTemplate.opsForValue().increment(newlyFans, 1);
            following = Boolean.TRUE;
            LOGGER.info("用户 {} 关注了 用户 {} ", UserUtils.getUid(), request.getFollowing());
        } else if(Objects.equals(relation.getIsDel(), 1))  {
            this.relationMapper.updateRelationById(relation.getId());
            following = Boolean.TRUE;
        } else {
            LOGGER.info("用户 {} 已经关注了 用户 {} ", UserUtils.getUid(), request.getFollowing());
        }
        if(following) {
            UserBehavior behavior = new UserBehavior();
            behavior.setId(this.uidGenerator.getUID());
            behavior.setBehaviorType(1);
            behavior.setFollowingId(relation.getFollowingId());
            behavior.setFollowerId(relation.getFollowerId());
            behavior.setIsUnfollow(0);
            behavior.setResolve(0);
            behavior.setUpdateTime(new Date());
            behavior.setCreateTime(new Date());
            this.userBehaviorMapper.insert(behavior);
        }

        Notification notification = new Notification();
        notification.setByUser(UserUtils.getUid());
        notification.setUid(request.getFollowing());
        notification.setType("following");
        notification.setCreateTime(new Date());
        this.rocketMQTemplate.syncSend("user-notifications", new GenericMessage(notification));

        Integer nowRelation = this.relationMapper.relation(UserUtils.getUid(), request.getFollowing());
        response.setRelation(nowRelation);
        response.setSuccess(true);
        return response;
    }

    @Override
    public FollowResponse unfollow(FollowRequest request) {
        FollowResponse response = new FollowResponse();
        Relation relation = this.relationMapper.selectOne(request.getFollowing(), UserUtils.getUid());
        if (Objects.isNull(relation)) {
            response.setSuccess(false);
            LOGGER.info("用户 {} 没有关注 用户 {} ", UserUtils.getUid(), request.getFollowing());
            return response;

        } else {
            UserBehavior follow = this.userBehaviorMapper.select(relation.getFollowingId(), relation.getFollowerId(), 1);
            UserBehavior unfollow = new UserBehavior();
            unfollow.setFollowingId(follow.getFollowingId());
            unfollow.setFollowerId(follow.getFollowerId());
            unfollow.setId(this.uidGenerator.getUID());
            unfollow.setOppositeId(follow.getId());
            unfollow.setBehaviorType(0);
            unfollow.setResolve(0);
            this.userBehaviorMapper.insert(unfollow);
            this.userBehaviorMapper.updateUnfollow2Yep(follow.getId());
            this.relationMapper.delRelationById(relation.getId());
            LOGGER.info("用户 {} 取消关注了 用户 {} ", UserUtils.getUid(), request.getFollowing());
        }
        response.setSuccess(true);
        return response;
    }

    @Override
    public FollowingsFollowersResponse followings(FollowingsFollowersRequest request) {
        Integer size = 20;
        if(Objects.nonNull(request.getPageSize())) {
            size = request.getPageSize();
        }
        PageHelper.startPage(request.getPageNum(), size);
        List<UserSimpleInfo> users = this.relationMapper.followings(UserUtils.getUid());

        PageInfo<UserSimpleInfo> pageInfo = new PageInfo<>(users);
        Page<UserSimpleInfo> page = new Page<>();
        page.setList(users);
        page.setPageNum(pageInfo.getPageNum());
        page.setPageSize(pageInfo.getPageSize());
        page.setTotal(pageInfo.getTotal());
        page.setLastPage(pageInfo.getLastPage());
        FollowingsFollowersResponse response = new FollowingsFollowersResponse();
        response.setUsers(page);
        return response;
    }

    @Override
    public FollowingsFollowersResponse followers(FollowingsFollowersRequest request) {
        Integer size = 20;
        if(Objects.nonNull(request.getPageSize())) {
            size = request.getPageSize();
        }
        PageHelper.startPage(request.getPageNum(), size);
        List<UserSimpleInfo> users = this.relationMapper.followers(UserUtils.getUid());
        PageInfo<UserSimpleInfo> pageInfo = new PageInfo<>(users);
        Page<UserSimpleInfo> page = new Page<>();
        page.setList(users);
        page.setPageNum(pageInfo.getPageNum());
        page.setPageSize(pageInfo.getPageSize());
        page.setTotal(pageInfo.getTotal());
        page.setLastPage(pageInfo.getLastPage());
        FollowingsFollowersResponse response = new FollowingsFollowersResponse();
        response.setUsers(page);
        return response;
    }
}
